﻿using HtmlAgilityPack;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using XjjXmm.FrameWork.Cache;
using XjjXmm.FrameWork.ToolKit;
using XjjXmm.Spider.biquge;

namespace XjjXmm.Spider.spider.FyxfcwCom;

internal class FyxfcwComSpider : ISiteSpider
{
    //https://www.zhihu.com/question/359676590/answer/1615531107

    //private readonly HttpClient _client;
    //private readonly ISqlSugarClient _sqlSugarClient;

    private readonly ClientBuildHelper<FyxfcwComSpider> buildHelper;

    private HttpClient _client => buildHelper.Client;

    public FyxfcwComSpider(ClientBuildHelper<FyxfcwComSpider> buildHelper)
    {
        buildHelper.Build();
        this.buildHelper = buildHelper;
    }


    public string Domain => GetSetting().Domain;

    public SiteSetting? GetSetting()
    {
        return Setting.FindSetting<FyxfcwComSpider>();
    }

    public ILogger GetLogger()
    {
        return Log.ForContext<FyxfcwComSpider>();
    }



    public async IAsyncEnumerable<string> FetchNovelLinks()
    {
        //全本
        //await foreach (var link in GetAllQuanBenLink())
        //{
        //    yield return link;
        //}

        //玄幻小说
        await foreach (var link in GetNovelLink(1))
        {
            yield return link;
        }

        //修真小说
        await foreach (var link in GetNovelLink(2))
        {
            yield return link;
        }

        //都市小说
        await foreach (var link in GetNovelLink(3))
        {
            yield return link;
        }

        //穿越小说
        await foreach (var link in GetNovelLink(4))
        {
            yield return link;
        }

        //网游小说
        await foreach (var link in GetNovelLink(5))
        {
            yield return link;
        }

        //科幻小说
        await foreach (var link in GetNovelLink(6))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink(7))
        {
            yield return link;
        }

    }


    protected async IAsyncEnumerable<string> GetAllQuanBenLink()
    {
        var url = "/wanben/1_1";
        while (true)
        {
            //完本小说
            var diectory = await _client.GetStringAsync(url);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(diectory);
            //*[@id="main"]/div[1]
            var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@id='newscontent']/div[@class='l']/ul/li");
            foreach (var node in nodes)
            {
                var zuopns = node.SelectSingleNode(".//span[@class='s2']/a");

                //Logger.Debug($"主题:{subjectNode.InnerText}");

                if (zuopns == null)
                {
                    continue;
                }


                var href = zuopns.Attributes["href"].Value;
                var text = zuopns.InnerText;

                //Logger.Debug($"{text}:{href}");

                yield return href;
            }

            await Task.Delay(5000);


            var nextPage = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='pagelink']/a[@class='next']");
            if (nextPage == null)
            {
                yield break;

            }

            url = nextPage.Attributes["href"].Value;


        }
        //*[@id="pagelink"]/a[class='next']
    }

   
    protected async IAsyncEnumerable<string> GetNovelLink(int category)
    {
        int page = 1;
        while (true)
        {
            var xuanhuanDiectory = await _client.GetStringAsync($"/ksl/{category}/{page}.html");
            var xuanhuanHtmlDoc = new HtmlDocument();
            xuanhuanHtmlDoc.LoadHtml(xuanhuanDiectory);

            var nodes = xuanhuanHtmlDoc.DocumentNode.SelectNodes("//ul[@class='txt-list txt-list-row5']/li");
            foreach (var node in nodes)
            {
                var zuopns = node.SelectSingleNode(".//span[@class='s2']/a");

                //Logger.Debug($"主题:{subjectNode.InnerText}");

                if (zuopns == null)
                {
                    continue;
                }


                var href = zuopns.Attributes["href"].Value;
                var text = zuopns.InnerText;

                //Logger.Debug($"{text}:{href}");

                yield return href;

                //var temp = await RedisClient.Instance.ListRightPush(keyArticle, href);
            }

            var totals = xuanhuanHtmlDoc.DocumentNode.SelectSingleNode("//ul[@class='pagination pagination-mga']/li/span").InnerText.Split('/').Last().Trim();

            if (totals == page.ToString())
            {
                yield break;
            }
            page++;

            await Task.Delay(5000);

        }
    }

  

    public async Task<NovelModel> FetchNovel(string url)
    {
        await Task.Delay(8000);
        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        var main = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='info']");

        var title = main.SelectSingleNode(".//h1").InnerText;
        var author = main.SelectSingleNode(".//p").InnerText.Replace("&nbsp;", "").Replace("作者：", "");

        var updateTime = main.SelectSingleNode(".//p[5]").InnerText.Replace("最后更新：", "").Trim().ToDateTime();
        var lastChapter = "";//main.SelectSingleNode(".//p[4]/a").InnerText.Trim();

        var category = main.SelectSingleNode(".//p[2]").InnerText.Replace("类别：", "").Trim();

        var isInstalment = main.SelectSingleNode(".//p[3]").InnerText.Replace("状态：", "").Trim() == "连载";

        var intro = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='desc xs-hidden']").InnerHtml;
        var novel = new NovelModel()
        {
            Title = title,
            Author = author,
            Category = category,
            UpdateTime = updateTime,
            LastChapter = lastChapter,
            IsInstalment = isInstalment,
            Intro = intro
        };

        return novel;
    }

    public async Task<string> FetchContent(string url)
    {
        await Task.Delay(5000);

        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        //*[@id="wrapper"]/div[4]/div/div[2]/h1
        var title = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='content']/h1").InnerText.Trim();
        var content = htmlDoc.DocumentNode.SelectNodes("//div[@id='content']/div[@class='posterror']/following-sibling::text()")
            .Select(t => t.InnerHtml).Concat("");
        //*[@id="content"]
        //*[@id="content"]/text()[1]
        return content;
    }


    /// <summary>
    /// 某一个小说的所有章节
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    public async IAsyncEnumerable<Chapter> FetchChapters(string url)
    {
        GetLogger().Information(Domain + ": 开始抓取章节列表：" + url);

        while (!string.IsNullOrEmpty(url))
        {
            var detai = await _client.GetStringAsync(url);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(detai);


            //var key = $"{title}:{author}";

            //await RedisClient.Instance.ListRightPush("detail", key);

            //await RedisClient.Instance.HashSet(key, "title", title);
            //await RedisClient.Instance.HashSet(key, "author", author);
            var paras = htmlDoc.DocumentNode.SelectNodes("(//ul[@class='section-list fix'])[2]/li"); //*[@id="list"]/dl/dd[1]/a
                                                                                                   //var paras = htmlDoc.DocumentNode.SelectNodes("//div[@id='list']/dl/dd"); //*[@id="list"]/dl/dd[1]/a
            foreach (var item in paras)
            {
                var link = item.SelectSingleNode(".//a");

                var href = link.Attributes["href"].Value;
                var text = link.InnerText;

                yield return new Chapter
                {
                    Title = text,
                    Link = href
                };
                //yield return new
                //{
                //    title = title,
                //    author = author,
                //    chapter = text,
                //    href = href
                //};
                // await RedisClient.Instance.ListRightPush(key, href);

                // await RedisClient.Instance.HashSet(key, text + "_href", href);
                // _logger.LogDebug($"{text}:{href}");
            }
            //*[@id="info"]

            await Task.Delay(5000);

            var next = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='listpage']/span[@class='right']/a");
            if(next == null)
            {
                url = "";
            }
            else if(next.Attributes["href"] == null)
            {
                url = "";
            }
            else
            {
                url = next.Attributes["href"].Value;
            }

        }
    }


}
